package controllers.tran;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.Session;

import play.db.jpa.JPABase;
import play.mvc.With;

import com.pany.cache.UserNameCache;
import com.pany.cache.VipNameCache;
import com.pany.domain.IConstant;
import com.pany.domain.IConstant.ICommonResultCode;
import com.pany.domain.IConstant.ITranResultCode;
import com.pany.domain.IConstant.IUserResultCode;
import com.pany.domain.models.Recharge;
import com.pany.domain.models.TranInfo;
import com.pany.domain.models.TranType;
import com.pany.domain.models.User;
import com.pany.domain.models.VIPInfo;
import com.pany.domain.req.AddRechargeReq;
import com.pany.domain.req.BatchAddTranReq;
import com.pany.domain.req.GetRechargeListReq;
import com.pany.domain.req.GetTranListReq;
import com.pany.domain.req.TranReq;
import com.pany.domain.rsp.AddRechargeRsp;
import com.pany.domain.rsp.GetRechargeListRsp;
import com.pany.domain.rsp.GetTranListRsp;
import com.pany.domain.rsp.TranRsp;
import com.pany.exceptions.ServiceException;
import com.pany.service.TranTypeService;
import com.pany.service.VIPInfoService;
import com.pany.utils.ServiceUtils;
import com.pany.utils.UUIDGenerator;

import controllers.BaseController;
import controllers.interceptor.UserSecure;
import controllers.user.UserController;

@With(UserSecure.class)
public class TranController extends BaseController
{
    
    public static void batchAddTranInfo()
    {
        BatchAddTranReq req = readObject(BatchAddTranReq.class);
        if (CollectionUtils.isEmpty(req.getTranTypeIdList()))
        {
            throw new ServiceException(ICommonResultCode.PARAMTER_IS_NULL, "消费列表");
        }
        
        // 获取会员信息同时进行鉴权
        VIPInfo vipInfo = VIPInfoService.vipLogin(req.getVipInfo());
        
        User user = getCurrentUser();
        
        Map<String, TranType> tranTypeIdMap = TranTypeService.getTranTypeMapByIdList(req.getTranTypeIdList());
        Double totalCost = 0D;
        
        Timestamp costTime = new Timestamp(new Date().getTime());
        for (String id : req.getTranTypeIdList())
        {
            TranInfo info = new TranInfo();
            TranType type = tranTypeIdMap.get(id);
            if (type == null || !IConstant.TRAN_TYPE_STATUS_ENABLE.equals(type.getStatus()))
            {
                throw new ServiceException(ITranResultCode.TRAN_TYPE_NOT_EXITS);
            }
            if (type.getDiscount() != null && type.getDiscount() > 0)// 如果存在打折情况,设置消费金额为打折后的金额
            {
                info.setConsume(type.getDiscount() / 10 * type.getPrice());
            }
            else
            {
                info.setConsume(type.getPrice());
            }
            
            info.setOriginalConsume(type.getPrice());
            
            totalCost += info.getConsume();
            
            // 设置ID
            info.setTranId(UUIDGenerator.generate());
            // 设置操作员
            info.setOperatorId(user.getUserId());
            
            info.setTranTime(costTime);
            
            info.setVipId(vipInfo.getVipId());
            info.save();
        }
        double remaining = vipInfo.getBalance() - totalCost;
        
        // 如果金额不足，交易失败
        if (remaining < 0)
        {// 余额不足
            throw new ServiceException(ITranResultCode.BALANCE_SHORTAGE_ERROR);
        }
        
        JPABase.em()
            .createQuery("update VIPInfo vip set vip.balance = vip.balance - ? where vip.vipId = ?")
            .setParameter(1, totalCost)
            // 原始金额减去消费后的金额
            .setParameter(2, vipInfo.getVipId())
            .executeUpdate();
        
        JPABase.em().flush();
        
        renderSuccess(null);
    }
    
    /**
     * 充值
     */
    public static void addRecharge()
    {
        AddRechargeReq req = readObject(AddRechargeReq.class);
        
        if (StringUtils.isEmpty(req.getVipName()))
        {
            throw new ServiceException(ICommonResultCode.PARAMTER_IS_NULL, "vipName");
        }
        if (req.getActualChargeCount() == null || req.getActualChargeCount() < 0)
        {
            throw new ServiceException(ICommonResultCode.PARAMTER_IS_ILLEGAL, "actualChargeCount");
        }
        if (req.getChargeCount() != null && req.getChargeCount() != 0
            && req.getChargeCount() < req.getActualChargeCount())
        {
            throw new ServiceException(ICommonResultCode.PARAMTER_IS_ILLEGAL, "chargeCount");
        }
        
        Recharge recharge = new Recharge();
        
        String cid = UUIDGenerator.generate();
        recharge.setChargeId(cid);
        recharge.setChargeDate(new Date());
        recharge.setOperatorId(getCurrentUser().getUserId());
        recharge.setActualSum(req.getActualChargeCount());
        
        if (req.getChargeCount() == null || req.getChargeCount().doubleValue() == 0D)
        {
            recharge.setChargeSum(recharge.getActualSum());
        }
        else
        {
            recharge.setChargeSum(req.getChargeCount());
        }
        
        VIPInfo vip = VIPInfoService.getVipBalanceByUname(req.getVipName());
        if (vip == null)
        {
            throw new ServiceException(IUserResultCode.VIP_NOT_EXSIT);
        }
        recharge.setVipId(vip.getVipId());
        
        JPABase.em()
            .createQuery("update VIPInfo set balance= balance+?")
            .setParameter(1, recharge.getChargeSum())
            .executeUpdate();
        
        recharge.save();
        
        AddRechargeRsp rsp = new AddRechargeRsp();
        rsp.setChargeId(cid);
        renderSuccess(rsp);
    }
    
    /**
     * 获取充值记录列表
     */
    public static void getRechargeList()
    {
        GetRechargeListReq req = readObject(GetRechargeListReq.class);
        GetRechargeListRsp rsp = new GetRechargeListRsp();
        int total = ServiceUtils.queryCountByCondition(req);
        if (total > 0)
        {
            rsp.setTotalNum(total);
            List<Recharge> list = (ServiceUtils.queryByCondition(req, Recharge.class));
            for (Recharge recharge : list)
            {
                recharge.setOperatorName(UserNameCache.getInstance().getCache(recharge.getOperatorId()));
                recharge.setVipName(VipNameCache.getInstance().getCache(recharge.getVipId()));
            }
            rsp.setRechargeList(list);
        }
        renderSuccess(rsp);
    }
    
    /**
     * 
     */
    public static void getTranList()
    {
        GetTranListReq req = readObject(GetTranListReq.class);
        GetTranListRsp rsp = new GetTranListRsp();
        rsp.setTotalNum(ServiceUtils.queryCountByCondition(req));
        if (rsp.getTotalNum() > 0)
        {
            List<TranInfo> list = (ServiceUtils.queryByCondition(req, TranInfo.class));
            rsp.setTransInfo(list);
        }
        renderSuccess(rsp);
    }
    
}
